package com.web.spider.util;

import org.apache.http.Consts;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * @Author cherrish
 * @Date 2019/8/29 15:31
 * @Version: 1.0
 * @Description
 */
public class HttpUtil {

    public HttpClientContext context;
    public CloseableHttpClient httpClient;

    /**
     * 构造时初始化全局变量
     */
    public HttpUtil(){
        // 全局请求设置
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).setSocketTimeout(10000).setConnectTimeout(10000).build();

        // 创建cookie store的本地实例
        CookieStore cookieStore = new BasicCookieStore();
        // 创建HttpClient上下文
        context = HttpClientContext.create();
        context.setCookieStore(cookieStore);
        // 创建一个HttpClient
        httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig)
                .setDefaultCookieStore(cookieStore).build();

    }


    /**
     * 静态一次性Get请求，获得html
     * @return
     */
    public static String getHtml(String url,String charSet){
        CloseableHttpClient client = HttpClients.createDefault();
        try {
            // 创建一个get请求用来获取必要的Cookie，如_xsrf信息
            HttpGet get = new HttpGet(url);
            CloseableHttpResponse res = client.execute(get);
            String html = EntityUtils.toString(res.getEntity(),charSet);
            StatusLine statusLine = res.getStatusLine();
            System.out.println("请求url:"+url+"返回代码：" + statusLine.getStatusCode());
            res.close();
            return html;

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 使用本类中的全局变量请求执行一次get请求
     * @return
     */
    public String doGet(String url,String charSet){
        try {
            // 创建一个get请求用来获取必要的Cookie，如_xsrf信息
            HttpGet get = new HttpGet(url);
            CloseableHttpResponse res = httpClient.execute(get,context);  //带上实例
            String html = EntityUtils.toString(res.getEntity(),charSet);
            res.close();
            return html;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 一次性post方法
     * @param url
     * @param nvps
     * @param charSet
     * @return
     */
    public String postHtml(String url, List<NameValuePair> nvps, String charSet) {
        CloseableHttpClient client = HttpClients.createDefault();
        try {
            // 构造post数据
//                List<NameValuePair> valuePairs = new LinkedList<NameValuePair>();
//                valuePairs.add(new BasicNameValuePair("email", name));
//                valuePairs.add(new BasicNameValuePair("password", password));
//                valuePairs.add(new BasicNameValuePair("remember_me", "true"));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, Consts.UTF_8);
//                entity.setContentType("application/x-www-form-urlencoded");  //提交其他类型在这修改，如提交json

            // 创建一个post请求
            HttpPost post = new HttpPost(url);
            // 注入post数据
            post.setEntity(entity);

            CloseableHttpResponse res = client.execute(post);
            String html = EntityUtils.toString(res.getEntity(), charSet);
            res.close();
            return html;

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }finally {
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 含上下文的post方法，可以用于模拟登陆，参数传入方法见注释掉的部分
     * @param url
     * @param nvps
     * @param charSet
     * @return
     */
    public String doPost(String url, List<NameValuePair> nvps,String charSet){
        try {
            // 构造post数据
//                List<NameValuePair> valuePairs = new LinkedList<NameValuePair>();
//                valuePairs.add(new BasicNameValuePair("email", name));
//                valuePairs.add(new BasicNameValuePair("password", password));
//                valuePairs.add(new BasicNameValuePair("remember_me", "true"));
            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(nvps, Consts.UTF_8);
//                entity.setContentType("application/x-www-form-urlencoded");  //提交其他类型在这修改

            // 创建一个post请求
            HttpPost post = new HttpPost(url);
            // 注入post数据
            post.setEntity(entity);

            CloseableHttpResponse res = httpClient.execute(post,context);
            String html = EntityUtils.toString(res.getEntity(), charSet);
            res.close();
            return html;

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 将对象中的httpClient实例释放掉
     */
    public  void shutdown(){
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        //一次性请求
        System.out.print(HttpUtil.getHtml("http://www.baidu.com","utf-8"));
        //模拟登陆
        HttpUtil httpUtil = new HttpUtil();
        //post等提交登陆的过程
        httpUtil.doGet("www.baidu.com","utf-8");  //继续用httpClient这个对象执行post get方法即可保持上下文、存储cookie等
        httpUtil.shutdown();//最后注意资源的释放
    }

// cookie获取
//                for (Cookie c : context.getCookieStore().getCookies()) {
//                    System.out.println(c.getName() + ": " + c.getValue());
//                }
}
